#include <string>
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstdlib>
#include "cJSON.h"
#include "Transcjson.h"


long count_of_data=0;  //count of data

void send_data(const void *data);

int main()
{
    int server_fd, client_fd;
    struct sockaddr_in server_addr, client_addr;  //
    socklen_t client_addr_len;
    char buf[1024];
    char buf_token[1024];
    // create a TCP socket
    server_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (server_fd < 0) {
        std::cerr << "Failed to create socket\n";
        return -1;
    }

    // bind to a specific IP address and port
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr("192.168.1.231"); // bind to a specific IP address
    server_addr.sin_port = htons(12345); // use port in USR-TCP232-304 <Serial Port>
    /*client_addr.sin_addr.s_addr = inet_addr("192.168.1.230");
    client_addr.sin_port = htons(12345);*/
    client_addr.sin_addr.s_addr = inet_addr("192.168.1.202");
    client_addr.sin_port = htons(65300);
    if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        std::cerr << "Failed to bind to port\n";
        return -1;
    }

    // listen for incoming connections
    if (listen(server_fd, 5) < 0) {
        std::cerr << "Failed to listen for connections\n";
        return -1;
    }

    std::cout << "Waiting for connections...\n";

    while (1) {
        // accept a new connection
        client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_addr_len);
        if (client_fd < 0) {
            std::cerr << "Failed to accept connection\n";
            continue;
        }
        std::cout << "Accepted connection from " << inet_ntoa(client_addr.sin_addr) << "\n";

        while (1) {
            // read data from the client
            int n = read(client_fd, buf, sizeof(buf)-1);
            if (n < 0) {
                std::cerr << "Failed to read data from client\n";
                break;
            } else if (n == 0) {
                std::cout << "Client closed the connection\n";
                break;
            } else {
                buf[n] = '\0';
                std::cout << "Received data: " << buf << "\n";

                // do something with the JSON data here...
                std::ifstream file_token;
                file_token.open("token.txt");
                char buf_token[1024];
                file_token>>buf_token;
                Transcjson t(buf_token,9090);
                std::string data;
                std::string *p_data;
                data=t.deal(buf,data);
                p_data=&data;
                send_data(p_data);
                // send thing about success to queue of messages

            }
        }

        close(client_fd);
        std::cout << "Closed connection with " << inet_ntoa(client_addr.sin_addr) << "\n";
    }

    close(server_fd);

    return 0;
}

void send_data(const void *data) {
    int server_fd,client_fd;
    struct sockaddr_in server_addr,client_addr;
    socklen_t client_addr_len;
    // create socket of UDP
    socket(PF_INET,SOCK_DGRAM,0);
    server_addr.sin_family=AF_INET;
    server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
    server_addr.sin_port=htons(9090);
    client_addr.sin_port=htons(9090);
    client_addr.sin_addr.s_addr=inet_addr( "192.168.1.1" );
    client_addr_len=sizeof(client_addr);
    if(bind(server_fd,(struct sockaddr*)&server_addr,sizeof(server_addr))==-1){
        perror("bind:");
        exit(1);
    }

    sendto(server_fd,data,sizeof (data),0,
           (struct sockaddr*)&client_addr,client_addr_len);
    //acceptance acknowledge from store
    char buf_token[1024];
    int len= recvfrom(server_fd,buf_token,1024,0,
                      (struct sockaddr*)&client_addr,&client_addr_len);
    if(len==-1) {
        perror("recvfrom:");
        exit(1);
        //send thing about fail to queue of message with the reason and the level
        //......
    }
    //create or open file of"data_count.txt" to count the thing that data were collected
    count_of_data++;
    std::ofstream file_data_count;
    file_data_count.open("home\\easy\\data\\edge\\data_count.txt");
    file_data_count<<count_of_data;
    //send thing of success of thing to queue of message
    //......


}
//确认ip信息
